//
// Created by jwhww on 25-9-23.
//

#ifndef JJ_RM_MOTOR_H
#define JJ_RM_MOTOR_H
//转矩常数
#define TORQUE_CONSTANT_GM6020                  (741.f)  //mN·m/A
#define TORQUE_CONSTANT_M3508                   (300.f)
#define TORQUE_CONSTANT_M2006                   (180.f)
//最大转矩
#define TORQUE_MAX_GM6020                       (1200.f)  //mN·m
#define TORQUE_MAX_M3508                        (3000.f)
#define TORQUE_MAX_M2006                        (1000.f)
//额定转速
#define SPEED_MAX_GM6020                        (320)  //rpm
#define SPEED_MAX_M3508                         (469)
#define SPEED_MAX_M2006                         (416)
//减速电机减速比
#define DECELERATION_RATIO_GM6020               (1.0f)
#define DECELERATION_RATIO_M3508                (19.203f)
#define DECELERATION_RATIO_M2006                (36.0f)
// 电机种类
typedef enum {
    MOTOR_TYPE_GM6020 = 0,
    MOTOR_TYPE_M3508,
    MOTOR_TYPE_M2006
}MotorType;
// 电机是否激活（被初始化）
typedef enum {
    DEACTIVATING = 0,
    ACTIVATING
}MotorActivated;
// 电机激活状态
typedef struct {
    MotorActivated GM6020;
    MotorActivated M3508;
    MotorActivated M2006;
}MotorActivatedGroup;
// 电机组
typedef enum {
    MOTOR_GROUP_1234_VOLTAGE = 0,     //电压控制voltage
    MOTOR_GROUP_5678_VOLTAGE,
    MOTOR_GROUP_1234_CURRENT,         //电流控制current
    MOTOR_GROUP_5678_CURRENT
}MotorGroup;
//电机ID
typedef enum {
    MOTOR_1 = 0,
    MOTOR_2,
    MOTOR_3,
    MOTOR_4,
    MOTOR_5,
    MOTOR_6,
    MOTOR_7,
    MOTOR_8,
}MotorID;
// 电机堵转状态
typedef enum {
    NOTBLOCKING = 0,
    BLOCKING_DOUBTFUL,
    BLOCKING_COMFIRM_POSITIVE,  //正堵转。堵转时电流为正
    BLOCKING_COMFIRM_NEGATIVE,  //负堵转。堵转时电流为负
    BLOCKING_BACK_FINISH,
}MotorBlockingStatus;
//电机堵转时数据
typedef struct {
    uint32_t time_when_blocking; // 电机堵转时的时间戳，单位：ms
    int16_t motor_angle;		// 电机转子角度, 0~8191
    int16_t motor_speed;		// 电机转子速度, rpm
    int16_t torque_current;		// 实际电机转矩电流, A
    int16_t data_back_reverse;           // 电机（反转数据）
}MotorBlockingData;
// 电机当前信息结构体
typedef struct
{
    // 电机基本信息
    PID_MOTOR Struct_Pid;       // 电机PID结构体IU
    MotorActivated MIT_Mode;          // 是否使用MIT模式
    MotorBlockingStatus blocking_status;          // 电机堵转状态
    MotorBlockingData blocking_data;          // 电机堵转数据
    //can相关
    MotorType motor_type;       // 电机种类（未来可以将总共24个超巨结构体合成为8个，通过这个地方来实现对不同类型电机的区分，反正数据都一样）
    uint16_t can_id;			// can ID，标识CAN报文的唯一ID ,这里写电机的
    int16_t set_voltage;		// ？电机设定电压, V
    int16_t motor_angle;		// 电机转子角度, 0~8191，虽然收报是uint但是你处理的时候可以加点料让它变成int
    int16_t motor_speed;		// 电机转子速度, rpm
    int16_t torque_current;		// 实际电机转矩电流, A
    uint8_t temperature;				// 电机温度，℃
}MotorInfo;
//==============================CAN全局变量==================================
//Tx相关
extern CAN_TxHeaderTypeDef TxHeader_can_GM6020; // CAN1发送消息头结构体，一个can总线只需要初始化一个
extern uint32_t Tx_mail_can_1[3];                     // CAN1发送邮箱号（用于标识发送缓冲区）
extern uint32_t Tx_mail_can_2[3];
extern uint8_t load_status;                    // 装载成功标志位 0-失败 1-成功
extern uint8_t can_send_content_motor[8];           // CAN发送数据内容
// Rx相关
extern CAN_RxHeaderTypeDef RxHeader_CAN2; // CAN1接收消息头结构体，一个can总线只需要初始化一个
extern uint8_t flag_can_receive;               //收报标志位 0-正在收报 1-收报完成
// 电机相关
extern MotorInfo Motor_Info_GM6020[8];	// 用户电机信息结构体实例，用于存储接收到的电机数据,表示电机当前信息。聚合初始化为0
extern MotorInfo Motor_Info_M3508[8];	// 用户电机信息结构体实例，用于存储接收到的电机数据,表示电机当前信息。聚合初始化为0
extern MotorInfo Motor_Info_M2006[8];	// 用户电机信息结构体实例，用于存储接收到的电机数据,表示电机当前信息。聚合初始化为0
extern MotorActivatedGroup Motor_Activated_Group;
extern uint8_t sin_table_1000[256];
// extern MotorActivated activating_motor[8];  // 该电机是否初始化, 0-未使用 1-已使用
//==============================CAN全局变量==================================
//==============================宏定义==================================

//==============================宏定义==================================
//==============================基础函数==================================
// 准备收发豹纹
int JJ_motor_init(MotorType motor_type);                                                                    //电机can相关初始化
void JJ_motor_data_load(const MotorID motor_id, const int16_t value);     //装载电机报文，一次最多控制4个电机
void JJ_motor_data_refresh(void);                                                                                     //重置报文装载篓子
// 收发豹纹
int JJ_motor_ctrl(CAN_HandleTypeDef *hcan, MotorType motor_type, MotorGroup motor_group);                           //向电机发报（开环控制直接用这个）
int JJ_motor_data_receive(CAN_HandleTypeDef *hcan);                                           //接收电机报文
// 蛋蛋鸡闭环控制
int16_t JJ_motor_position_closeCircle(int target_positon, MotorInfo *motor_info,
                            const MotorID motor_id);      //单电机位置闭环，输入0~8191
int16_t JJ_motor_angle_closeCircle(float target_angle, MotorInfo *motor_info,
                         const MotorID motor_id);         //单电机角度闭环, 输入0~359.99°（逆时针），其实和位置是一个东西，单位不同而已
int16_t JJ_motor_speed_closeCircle(int16_t target_speed, MotorInfo *motor_info,
                         const MotorID motor_id);         //单电机速度闭环
int16_t JJ_motor_torque_closeCircle(float target_torque, MotorInfo *motor_info,
                         const MotorID motor_id);        //单电机力矩闭环
int16_t JJ_motor_P_S_closeCircle(int target_position, MotorInfo *motor_info,
                       const MotorID motor_id);                                                                     //单电机位置速度串级闭环
int16_t JJ_motor_P_T_closeCircle(int target_position, MotorInfo *motor_info,
                       const MotorID motor_id);                                                                     //单电机位置-力矩串级闭环
int16_t JJ_motor_S_T_closeCircle(int16_t target_speed, MotorInfo *motor_info,
                                 const MotorID motor_id);                                                           //单电机速度-力矩串级闭环
int16_t JJ_motor_MIT_closeCircle(MotorInfo *motor_info,float target_torque_frontFeed, int target_position, int16_t target_speed, const MotorID motor_id);           //MIT：力矩前馈的位置-速度并级闭环
//==============================基础函数==================================

#endif //JJ_RM_MOTOR_H